Bienvenidas a otra sesión de Pyladies!!

En esta ocasión lo que haremos será continuar aprendiendo a usar la biblioteca para análisis de datos llamada Pandas!!

En la introducción de pandas vimos Series, 'Data Frames' y como crearlos, además vimos como podemos acceder a un subgrupo de elementos tanto en series como en data frames. Está sesión va a estar más enfocada a ver como manipular y ordenar tus datos y análisis estadísticos básicos.

Sin más preámbulo comenzamos!!! :)

Iniciaremos cargando los paquetes necesarios y creando unos arreglos de datos.


In [1]:
#Cargamos los paquetes necesarios

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

In [3]:
#Creamos arreglos de datos por un arreglo de numpy

arreglo = np.random.randn(7,4)
columnas = list('ABCD')
df = pd.DataFrame(arreglo, columns=columnas )
df


Out[3]:
A B C D
0 0.131053 -0.860202 0.281749 -0.625497
1 1.155817 1.640577 0.736785 1.142968
2 -0.962845 1.402777 -0.704439 0.636314
3 0.798315 -0.398095 1.791975 0.263193
4 -1.446837 0.553332 -0.939147 -1.711504
5 1.116232 0.465874 0.529144 -2.296299
6 1.265890 0.160612 -0.746620 2.118032

In [11]:
#Creamos arreglo de datos por diccionario 

df2 = pd.DataFrame({'Orden':list(range(5)),'Valor': np.random.random_sample(5),
                      'Categoría':['a', 'a', np.nan, 'b', 'b']})

In [12]:
df2


Out[12]:
Categoría Orden Valor
0 a 0 0.293650
1 a 1 0.105914
2 NaN 2 0.833202
3 b 3 0.854258
4 b 4 0.480150

In [14]:
#Creamos arreglo de datos desde archivo existente

df3 = pd.read_csv('titanic.csv', header=0)
df3.head()


Out[14]:
Pclass Sex Age SibSp Parch Fare Survived
0 3 1 22.0 1 0 7.2500 0
1 1 0 38.0 1 0 71.2833 1
2 3 0 26.0 0 0 7.9250 1
3 1 0 35.0 1 0 53.1000 1
4 3 1 35.0 0 0 8.0500 0

Ya que tenemos hechos nuestros arreglos, ahora vamos a ver las características generales de ellos...


In [15]:
#¿cuáles son los índices?

df.index


Out[15]:
RangeIndex(start=0, stop=7, step=1)

In [16]:
#¿cuáles son las etiquetas?

df.columns


Out[16]:
Index(['A', 'B', 'C', 'D'], dtype='object')

In [17]:
#¿qué valores contiene mi arreglo?

df.values


Out[17]:
array([[ 0.13105293, -0.86020212,  0.2817491 , -0.62549666],
       [ 1.15581654,  1.64057737,  0.73678538,  1.14296846],
       [-0.96284517,  1.40277673, -0.70443887,  0.63631411],
       [ 0.79831518, -0.39809476,  1.79197503,  0.26319252],
       [-1.44683719,  0.55333218, -0.93914695, -1.71150372],
       [ 1.11623171,  0.46587416,  0.52914362, -2.29629905],
       [ 1.26589029,  0.16061153, -0.74662032,  2.11803193]])

In [20]:
# Ahora vamos a ver un resumen de nuestros datos

df.describe()


Out[20]:
A B C D
count 7.000000 7.000000 7.000000 7.000000
mean 0.293946 0.423554 0.135635 -0.067542
std 1.099577 0.899160 0.993336 1.572055
min -1.446837 -0.860202 -0.939147 -2.296299
25% -0.415896 -0.118742 -0.725530 -1.168500
50% 0.798315 0.465874 0.281749 0.263193
75% 1.136024 0.978054 0.632965 0.889641
max 1.265890 1.640577 1.791975 2.118032

In [21]:
#si quieres saber qué más hace este método ejecuta este comando
df.describe?

Ejercicio 1

Crea un data frame de la clase de pyladies que contenga la información de los miembros. Cada fila va a ser un miembro y cada columna una cualidad que describa a esos miembros. Las columnas serán las siguientes: Edad, Estatura, Origen(ciudad), Grado(estudios), Género(codificado con 0 y 1)


In [ ]:


In [ ]:

Ordenando tu arreglo

Imagina que quieres que tus datos se presenten en diferente orden en tu arreglo de datos porque de esta forma se pueden entender mejor, o es el formato que te piden en tu trabajo o simplemente porque te gusta más. Para esto usamos los métodos de 'sort'


In [23]:
#Ordenamiento por valores en las columnas

df2.sort_values(by='Valor')


Out[23]:
Categoría Orden Valor
1 a 1 0.105914
0 a 0 0.293650
4 b 4 0.480150
2 NaN 2 0.833202
3 b 3 0.854258

In [24]:
#Ordenamiento por etiquetas de las columnas

df.sort_index(axis=1, ascending=False)


Out[24]:
D C B A
0 -0.625497 0.281749 -0.860202 0.131053
1 1.142968 0.736785 1.640577 1.155817
2 0.636314 -0.704439 1.402777 -0.962845
3 0.263193 1.791975 -0.398095 0.798315
4 -1.711504 -0.939147 0.553332 -1.446837
5 -2.296299 0.529144 0.465874 1.116232
6 2.118032 -0.746620 0.160612 1.265890

Ejercicio 2

Haz un data frame que contenga a los 3 miembros con menor estatura, de modo que el data frame contenga sólo el nombre y la estatura


In [ ]:


In [ ]:

Buscando valores específicos en nuestros datos

Cuando analizas datos no siempre van a estar todos ordenaditos, filtrados y arreglados de tal modo que tu puedas hacer las computaciones necesarias para el anális. De hecho lo más frecuente es que te encuentres con datos faltantes o valores innecesarios o cosas que no quieres y/o necesitas para tu análisis.

Como ejemplo toma el segundo data frame que hicimos, te das cuenta que hay un 'NaN' por ahí que simplemente representa un valor faltante.

¿Qué harías en este caso?

y una vez que decidiste hacerlo, ¿Cómo lo lograrías?

Por suerte pandas tiene unos métodos para encontrar valores específicos o faltantes, y formas de lidiar con ellos...


In [25]:
# Primero vamos a buscar valores específicos en una columna de nuestros datos

df2.Categoría.isin(['A', 'B', 'b'])


Out[25]:
0    False
1    False
2    False
3     True
4     True
Name: Categoría, dtype: bool

In [26]:
# Ahora veremos en todo el arreglo

df2.isin(['A', 'B', 'b'])


Out[26]:
Categoría Orden Valor
0 False False False
1 False False False
2 False False False
3 True False False
4 True False False

In [27]:
# Busquemos valores vacíos

pd.isnull(df2)


Out[27]:
Categoría Orden Valor
0 False False False
1 False False False
2 True False False
3 False False False
4 False False False

In [28]:
# ¿qué hacemos con este? ¿lo botamos?

df2.dropna(how='any')


Out[28]:
Categoría Orden Valor
0 a 0 0.293650
1 a 1 0.105914
3 b 3 0.854258
4 b 4 0.480150

In [29]:
# ¿o lo llenamos diferente?
df2.fillna(value='c')


Out[29]:
Categoría Orden Valor
0 a 0 0.293650
1 a 1 0.105914
2 c 2 0.833202
3 b 3 0.854258
4 b 4 0.480150

Estadísticos básicos

Podemos ver rápidamente como se comportan nuestros datos sacando estadísticos. Normalmente tendrías que hacerlo para cada condición de forma 'manual', sin embargo pandas nos permite hacerlo de forma muy fácil y muy rápida (en comparación con los for loops).

Veamos unos ejemplos.


In [30]:
#obtener promedio por columna
df.mean()


Out[30]:
A    0.293946
B    0.423554
C    0.135635
D   -0.067542
dtype: float64

In [31]:
#obtener promedio por fila
df.mean(1)


Out[31]:
0   -0.268224
1    1.169037
2    0.092952
3    0.613847
4   -0.886039
5   -0.046262
6    0.699478
dtype: float64

In [33]:
#varianza por columna
df.var()


Out[33]:
A    1.209070
B    0.808489
C    0.986716
D    2.471358
dtype: float64

In [34]:
#varianza por fila
df.var(1)


Out[34]:
0    0.313325
1    0.136682
2    1.253808
3    0.856333
4    1.023499
5    2.335811
6    1.571565
dtype: float64

In [38]:
#Frecuencia de valores en una columna específica (series)
df2.Categoría.value_counts()


Out[38]:
a    2
b    2
Name: Categoría, dtype: int64

In [42]:
#Aplicar una función para todo el data frame
print(df)
df.apply(np.sum) #suma por columna


          A         B         C         D
0  0.131053 -0.860202  0.281749 -0.625497
1  1.155817  1.640577  0.736785  1.142968
2 -0.962845  1.402777 -0.704439  0.636314
3  0.798315 -0.398095  1.791975  0.263193
4 -1.446837  0.553332 -0.939147 -1.711504
5  1.116232  0.465874  0.529144 -2.296299
6  1.265890  0.160612 -0.746620  2.118032
Out[42]:
A    2.057624
B    2.964875
C    0.949447
D   -0.472792
dtype: float64

In [44]:
df.apply(np.square) # elevar valores al cuadrado


Out[44]:
A B C D
0 0.017175 0.739948 0.079383 0.391246
1 1.335912 2.691494 0.542853 1.306377
2 0.927071 1.967783 0.496234 0.404896
3 0.637307 0.158479 3.211175 0.069270
4 2.093338 0.306177 0.881997 2.929245
5 1.245973 0.217039 0.279993 5.272989
6 1.602478 0.025796 0.557442 4.486059

In [45]:
#solo para comprobar
0.131053**2


Out[45]:
0.017174888809

Ejercicio 3

Con el data frame de Pyladies haz lo siguiente:

  1. Obtén el promedio de edades y estaturas de los miembros de Pyladies
  2. Obtén un conteo de los orígenes de los miembros de Pyladies
  3. Obtén el índice de masa corporal asumiendo que el promedio de peso es 60kg, ese resultado ponlo como una columna nueva del data frame

In [ ]:


In [ ]:


In [ ]:

Combinar arreglos

A veces tenemos todos los datos que queremos analizar distribuidos en diferentes arreglos de datos y luego no sabemos como combinarlos. Para ello pandas tiene diferentes métodos que nos ayudan en esta tarea.


In [56]:
#Concatenar los dos data frames

pd.concat([df, df2])


Out[56]:
A B C Categoría D Orden Valor
0 0.131053 -0.860202 0.281749 NaN -0.625497 NaN NaN
1 1.155817 1.640577 0.736785 NaN 1.142968 NaN NaN
2 -0.962845 1.402777 -0.704439 NaN 0.636314 NaN NaN
3 0.798315 -0.398095 1.791975 NaN 0.263193 NaN NaN
4 -1.446837 0.553332 -0.939147 NaN -1.711504 NaN NaN
5 1.116232 0.465874 0.529144 NaN -2.296299 NaN NaN
6 1.265890 0.160612 -0.746620 NaN 2.118032 NaN NaN
0 NaN NaN NaN a NaN 0.0 0.293650
1 NaN NaN NaN a NaN 1.0 0.105914
2 NaN NaN NaN NaN NaN 2.0 0.833202
3 NaN NaN NaN b NaN 3.0 0.854258
4 NaN NaN NaN b NaN 4.0 0.480150

In [57]:
#ahora por columnas

pd.concat([df, df2], axis=1)


Out[57]:
A B C D Categoría Orden Valor
0 0.131053 -0.860202 0.281749 -0.625497 a 0.0 0.293650
1 1.155817 1.640577 0.736785 1.142968 a 1.0 0.105914
2 -0.962845 1.402777 -0.704439 0.636314 NaN 2.0 0.833202
3 0.798315 -0.398095 1.791975 0.263193 b 3.0 0.854258
4 -1.446837 0.553332 -0.939147 -1.711504 b 4.0 0.480150
5 1.116232 0.465874 0.529144 -2.296299 NaN NaN NaN
6 1.265890 0.160612 -0.746620 2.118032 NaN NaN NaN

Hay muchos otros métodos más para combinar data frames los cuales podemos encontrar en la siguiente página

Agrupamiento

Hay veces que tenemos datos sobre los cuales queremos operar los cuales pueden dividirse en un subgrupo de categorías. Para esto usamos la herramienta 'Groupby'.

Cuando pensamos en agrupamiento podemos hacer referencia a las siguientes situaciones:

  1. Vamos a dividir el data frame en subgrupos
  2. vamos a aplicar una función específica a cada subgrupo
  3. Vamos a combinar los resultados en otro data frame

In [60]:
#Agruparemos el tercer data frame por sobrevivencia
df3.groupby('Survived').mean()


Out[60]:
Pclass Sex Age SibSp Parch Fare
Survived
0 2.530706 0.853346 33.256645 0.555454 0.32539 22.140653
1 1.951542 0.318649 30.414596 0.474302 0.46696 48.496899

In [61]:
df3.head()


Out[61]:
Pclass Sex Age SibSp Parch Fare Survived
0 3 1 22.0 1 0 7.2500 0
1 1 0 38.0 1 0 71.2833 1
2 3 0 26.0 0 0 7.9250 1
3 1 0 35.0 1 0 53.1000 1
4 3 1 35.0 0 0 8.0500 0

In [62]:
#ahora lo agruparemos por sobrevivencia y sexo
df3.groupby(['Survived', 'Sex']).mean()


Out[62]:
Pclass Age SibSp Parch Fare
Survived Sex
0 0 2.850000 28.681250 1.218750 1.006250 22.953674
1 2.475832 34.042965 0.441461 0.208378 22.000928
1 0 1.918103 30.864224 0.515086 0.517241 52.063156
1 2.023041 29.453180 0.387097 0.359447 40.871353

In [ ]: